﻿ using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TheCell;

namespace SudoCalc
{
    public class CombinationUtils
    {
        public static void CombinationPossible(Dictionary<int, List<Cell>> Lines, Dictionary<int, List<Cell>> Columns, Dictionary<int, List<Cell>> Area)
        {
            CombinationDictionary = Combination(Lines, Columns, Area);
        }
        public static Dictionary<int, List<List<Cell>>> CombinationDictionary
        {
            get;
            private set;
        }
        private static Dictionary<int, List<List<Cell>>> Combination(Dictionary<int, List<Cell>> Lines, Dictionary<int, List<Cell>> Columns, Dictionary<int, List<Cell>> Areas)
        {
            Dictionary<int, List<Cell>> Linepossible = Filtration(Lines);
            Dictionary<int, List<Cell>> Columpossible = Filtration(Columns);
            Dictionary<int, List<Cell>> Areapossible = Filtration(Areas);

            Dictionary<int, List<List<Cell>>> LineCombination = ZoneCombination(Linepossible);
            Dictionary<int, List<List<Cell>>> ColumCombination = ZoneCombination(Columpossible);
            Dictionary<int, List<List<Cell>>> AreaCombination = ZoneCombination(Areapossible);

            Dictionary<int, List<List<Cell>>> combination = new Dictionary<int, List<List<Cell>>>();
            combination = marge(LineCombination, combination);
            combination = marge(ColumCombination, combination);
            combination = marge(AreaCombination, combination);
            return combination;
        }

        private static Dictionary<int, List<Cell>> Filtration(Dictionary<int, List<Cell>> Zone)
        {
            Dictionary<int, List<Cell>> filtration = new Dictionary<int, List<Cell>>();
            foreach (KeyValuePair<int, List<Cell>> item in Zone)
            {
                List<Cell> filteredcell = Filtrationcell(item.Value);
                filtration.Add(item.Key, filteredcell);
            }
            return filtration;
        }

        private static List<Cell> Filtrationcell(List<Cell> item)
        {
            List<Cell> filteredcell = new List<Cell>();
            foreach (Cell cell in item)
            {
                if (cell.Possible.Count > 1)
                {
                    filteredcell.Add(cell);
                }
            }
            return filteredcell;
        }

        private static Dictionary<int, List<List<Cell>>> ZoneCombination(Dictionary<int, List<Cell>> zonepossible)
        {
            Dictionary<int, List<List<Cell>>> combination = new Dictionary<int, List<List<Cell>>>();
            List<List<Cell>> part = new List<List<Cell>>();
            /* List<Cell> possible = new List<Cell>();
            List<Cell> mindem = null;*/
            foreach (KeyValuePair<int, List<Cell>> possibles in zonepossible)
            {
                for (int i = 3; i <= possibles.Value.Count; i++)
                {
                    part = Combinationpossible(possibles.Value, i);
                    combination.Add(i, part);
                }
                
            }
            return combination;
        }

        private static List<List<Cell>> Combinationpossible (List<Cell> possibles,int i)
        {
            List<List<Cell>> list = new List<List<Cell>>();
            for (int index = 1; index <= i; index++)
            {
                List<List<Cell>> l = new List<List<Cell>>();
                if (list.Count != 0)
                {
                    foreach (Cell cell in possibles)
                    {
                        for(int j = 1; j <= possibles.Count; j++)
                        {
                            if (!list[index].Contains(cell))
                            {
                                list = Copy(list);
                            }
                        }          
                    }
                }
                else
                {
                    list = Initialize(possibles, list);
                }               
            }
            return list;
        }

        private static List<List<Cell>> Initialize(List<Cell> possibles, List<List<Cell>> list)//应该存指针
        {
            List<Cell> result = new List<Cell>();
            for (int i = 1; i <= possibles.Count;i++)
            {
                foreach (Cell cell in possibles)
                {
                    result.Add(possibles[i]);
                    list.Add(result);
                }
            }
            return list;
        }

        private static List<List<Cell>> Copy(List<List<Cell>> list)//复制数组指针而不是值对象
        {
            List<List<Cell>> L = new List<List<Cell>>();

            return L;
        }

        private static Dictionary<int, List<List<Cell>>> marge(Dictionary<int, List<List<Cell>>> ZoneCombination, Dictionary<int, List<List<Cell>>> combination)
        {
            foreach (KeyValuePair<int, List<List<Cell>>> item in ZoneCombination)
            {
                combination.Add(item.Key, item.Value);
            }
            return combination;
        }
    }
}
